using System;
using System.Collections;
using System.Web.Caching;
using System.Xml;
using CommunityServer.Components;
using CommunityServer.Configuration;
using System.Reflection;
using System.Reflection.Emit;
using System.ComponentModel;

namespace FourRoads.Links
{
	public class SkinExtensionProperty
	{
		public SkinExtensionProperty()
		{
		}

		public SkinExtensionProperty(string name , string dataValue ,  string dataItem)
		{
			_Name = name;
			_DataValue = dataValue;
			_DataItem = dataItem;
		}

		private string _Name = string.Empty;
		public string Name
		{
			get
			{
				return _Name;
			}
		}

		private string _DataValue = string.Empty;
		public string DataValue
		{
			get
			{
				return _DataValue;
			}
		}

		private string _DataItem = string.Empty;
		public string DataItem
		{
			get
			{
				return _DataItem;
			}
		}
	}
	
	public class SkinExtension
	{
		public SkinExtension()
		{
		}

		public SkinExtension(SkinExtensionProperty[] propItems , string name, string skinName)
		{
			_PropItems = propItems;
			_SkinName = skinName;
			_Name = name;
		}

		private string _Name = string.Empty;
		public string Name
		{
			get
			{
				return _Name;
			}
		}

		private SkinExtensionProperty[] _PropItems = new SkinExtensionProperty[0];
		public SkinExtensionProperty[] Properties
		{
			get
			{
				return _PropItems;
			}
		}

		private string _SkinName = string.Empty;
		public string SkinName
		{
			get
			{
				return _SkinName;
			}
		}
	}

	/// <summary>
	/// Summary description for ResLinkConfiguration.
	/// </summary>
	[Serializable]
	public class ResLinkConfiguration : ApplicationConfiguration
	{
		public ResLinkConfiguration()
		{

		}

		[NonSerialized() , ReadFromConfigurationFileOnly()]
		public  SkinExtension[] SkinExtensions = new SkinExtension[0];

		public static ResLinkConfiguration Instance()
		{
			return Instance(true);
		}

		public static ResLinkConfiguration Instance(bool useCache)
		{
			return Instance(typeof(ResLinkConfiguration), useCache) as ResLinkConfiguration;
		}
	
		protected override string ConfigSection
		{
			get { return "CommunityServer/ResLinkConfiguration"; }
		}

		public override ApplicationType ApplicationType
		{
			get { return (ApplicationType)ExApplicationType.ResLink; }
		}

		protected override void Initialize(XmlNode node)
		{
			base.Initialize(node);

			if(node != null)
			{
				XmlAttributeCollection attcol = node.Attributes;

				UpdateAttribute(attcol , "HideDisabledSections");
				UpdateAttribute(attcol , "DisplaySectionCounts");
				UpdateAttribute(attcol , "DisplayLinkCounts");
				UpdateAttribute(attcol , "AnonymousRatings");
				UpdateAttribute(attcol , "PromoteLinksIntoParentSections");

				PopulateExtensions(node);
		
			}
		}

		protected void UpdateAttribute(XmlAttributeCollection attcol , string propName)
		{
			XmlAttribute att = attcol[propName];
			if ( att != null)
			{
				PropertyInfo pi = this.GetType().GetProperty(propName);

				System.Type srcType = propName.GetType();
				TypeConverter ti = TypeDescriptor.GetConverter(pi.PropertyType);

				if (ti.CanConvertFrom(srcType))
				{
					object output = new object();
					pi.SetValue( this , ti.ConvertFrom( att.Value )  , null);
				}
			}
		}

		protected void PopulateExtensions(XmlNode node)
		{
			XmlNodeList templates = node.SelectNodes("Template/SkinExtension");

			ArrayList templateArray = new ArrayList(templates.Count);

			foreach(XmlNode props in templates)
			{
				XmlNodeList items = props.SelectNodes("property");

				ArrayList propArray = new ArrayList(items.Count);

				foreach(XmlNode item in items)
				{
					XmlAttribute att = item.Attributes["DataItem"];
					
					string dataItem = string.Empty;

					if (att != null)
						dataItem = att.Value;

					propArray.Add(new SkinExtensionProperty
						( item.Attributes["Name"].Value , item.Attributes["DataValue"].Value , dataItem));
				}

				SkinExtension newProps = new SkinExtension(
					(SkinExtensionProperty[]) propArray.ToArray(typeof(SkinExtensionProperty)),
					props.Attributes["Name"].Value,
					props.Attributes["SkinName"].Value);

				templateArray.Add(newProps);
			}

			SkinExtensions = (SkinExtension[])templateArray.ToArray(typeof(SkinExtension));
		}

		private bool _DisplayLinkCounts = false;
		public bool DisplayLinkCounts
		{
			get
			{
				return _DisplayLinkCounts;
			}
			set 
			{ 
				_DisplayLinkCounts = value;
			}
		}

		private bool _AnonymousRatings = false;
		public bool AnonymousRatings
		{
			get
			{
				return _AnonymousRatings;
			}
			set 
			{ 
				_AnonymousRatings = value;
			}
		}

		private bool _PromoteLinksIntoParentSections = false;
		public bool PromoteLinksIntoParentSections
		{
			get
			{
				return _PromoteLinksIntoParentSections;
			}
			set 
			{ 
				_PromoteLinksIntoParentSections = value;
			}
		}

		private int _AdvertRepeatFrequency = 20;
		public int AdvertRepeatFrequency
		{
			get
			{
				return _AdvertRepeatFrequency;
			}
			set 
			{ 
				_AdvertRepeatFrequency = value;
			}
		}

		private bool _HideDisabledSections = true;
		public bool HideDisabledSections
		{
			get
			{
				return _HideDisabledSections;
			}
			set 
			{ 
				_HideDisabledSections = value;
			}
		}

		private bool _DisplaySectionCounts = false;
		public bool DisplaySectionCounts
		{
			get
			{
				return _DisplaySectionCounts;
			}
			set 
			{ 
				_DisplaySectionCounts = value;
			}
		}
	}
}
